18

1、简单的小示例

const Koa=require('koa');    //引入Koa.js
const app=new Koa();        //实例化Koa对象

const main=ctx=>{    //main函数用来设置ctx.response.body
    ctx.response.body='Hello World';    //context.response.body就是发给用户的消息
}

app.use(main);    //加载main函数
app.listen(3000);    //创建服务器并监听3000端口

2、HTTP Response 的类型

//Koa 默认的返回类型是text/plain,如果想返回其他类型的内容,可以先用ctx.request.accepts判断一下,客户端希望接受什么数据(根据 HTTP Request 的Accept字段),然后使用ctx.response.type指定返回类型

const Koa=require('koa');
const app=new Koa();

const main=ctx=>{
    if(ctx.require.accepts('xml')){
        ctx.response.type='xml';
        ctx.response.body='<data>Hello</data>'
    }else if(ctx.require.accepts('json')){
        ctx.response.type='json';
        ctx.response.body={data:'Hello'};
    }else if(ctx.require.accepts('html')){
        ctx.response.type='html';
        ctx.response.body='<p>Hello</p>'
    }else{
        ctx.response.type='text';
        ctx.response.body='Hello';
    }
}

app.use(main);
app.listen(3000);

3、路由(封装好的 koa-route模块)

const Koa=require('koa');
const app=new Koa();
const route=require('koa-route');

const about=ctx=>{
    ctx.response.type='html';    //给客户端发送的消息类型是html
    ctx.response.body='<a href='/'>去首页</a>'    //发送的内容
}

const main=ctx=>{
    ctx.response.type='html';
    ctx.response.body='<p>我是首页</p>'
}

app.use(route.get('/',main));    //当客户端访问根路径时,返回main函数
app.use(route.get('/about',about));
app.listen(3000);

4、 静态资源

//如果网站提供静态资源(图片、字体、样式表、脚本......),不必为它们一个个写路由,koa-static模块封装了这部分的请求
const path=require('path');
const serve=require('koa-static');

const main=serve(path.join(__dirname));
app.use(main);

5、重定向

//有些场合,服务器需要重定向(redirect)访问请求。比如,用户登陆以后,将他重定向到登陆前的页面。ctx.response.redirect()方法可以发出一个 302 跳转,将用户导向另一个路由。
const Koa=require('koa');
const app=new Koa();
const route=require('koa-route');

const redirect=ctx=>{
    ctx.response.redirect('/');    //将用户重定向到首页
}
const main=ctx=>{
    ctx.response.type='html';
    ctx.response.body='<a href='/'>首页</a>';
}

app.use(route.get('/redirect',redirect));
app.use(route.get('/',main));

app.use(main);
app.listen(3000);

6、中间件

1、打印日志(Logger功能):
    const main=ctx=>{
        cxt.response.body='Hello';
        console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`)    //1502144902843 GET /
    }
    
    
2、什么是中间件?
    //基本上,Koa 所有的功能都是通过中间件实现的。
    //代码中的logger、main函数就叫做中间件(middleware),因为它处在 HTTP Request 和 HTTP Response 中间,用来实现某种中间功能。app.use()用来加载中间件
    //每个中间件默认接受两个参数,第一个参数是 Context 对象,第二个参数是next函数。只要调用next函数,就可以把执行权转交给下一个中间件
    const logger=(ctx,next)=>{
        console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`)
    }
    const main=ctx=>{
        ctx.response.body='<p>Hello</p>';
    }
    app.use(logger);
    app.use(main);
    app.listen(3000);
    
    
3、异步中间件
    const fs=require('fs.promised');
    const Koa=require('koa');
    const app=new Koa();
    
    const main=async function(ctx,next){    //async表示该函数时异步函数(ES6语法)
        ctx.response.type='html';
        ctx.response.body=await fs.readFile('./demos/template.html','utf8')
    }
    app.use(main);
    app.listen(3000);
    
    
4、中间件的合成
    //koa-compose模块可以将多个中间件合成为一个
    const Koa=require('koa');
    const app=new Koa();
    const compose=require('koa-compose');
    
    const logger=(ctx,next)=>{
        console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`);
        next()
    }
    
    const main=ctx=>{
        ctx.response.body='Hello';
    }
    
    const middlewares=compose([logger,main]);
    app.use(middlewares);

7、错误处理

1、抛出 500错误、404错误
    const main=ctx=>{
        ctx.response.status=404;    //等同于:ctx.throw(404)
        ctx.response.body='找不到页面';
    }
   
   
2、处理错误的中间件
    //main函数抛出错误,被handler函数捕获
    const handler=async function(ctx,next){
        tr{
            await next();
        }catch(err){
            ctx.response.status=err.statusCode||err.status||500;
            ctx.response.body={
                message:err.message
            }
        }
    }
    
    const main=ctx=>{
        ctx.throw(500);
    }
    app.use(handler);
    app.use(main);
    
    
3、error 事件的监听
    //运行过程中一旦出错,Koa 会触发一个error事件。监听这个事件,也可以处理错误
    const main=ctx=>{
        ctx.throw(500);
    }
    
    app.on('error',(err,ctx)=>{
        console.error('服务器出错了',err)
    })
4、释放error事件
        //如果错误被try...catch捕获,就不会触发error事件,这时,必须调用ctx.app.emit(),手动释放error事件,才能让监听函数生效
        const handler = async (ctx, next) => {
            try {
                await next();
            } catch (err) {
                ctx.response.status = err.statusCode || err.status || 500;
                ctx.response.type = 'html';
                ctx.response.body = '<p>Something wrong, please contact administrator.</p>';
                ctx.app.emit('error', err, ctx);
            }
          };
        
          const main = ctx => {
              ctx.throw(500);
          };
        
          app.on('error', function(err) {
              console.log('logging error ', err.message);
              console.log(err);
          });

8、Web App 的功能

1、Cookies
    //ctx.cookies.get('cookieName') 用来读 Cookie
    //ctx.cookies.set('cookieName',value) 用来写Cookie
    const main=ctx=>{    //你会看到1 views。刷新一次页面,就变成了2 views
        const n=Number(ctx.cookies.get('view')||0)+1;
        ctx.cookies.set('view',n);
        ctx.response.body=n+'view';
    }
    
2、表单
    //koa-body模块可以用来从 POST 请求的数据体里面提取键值对
    const Koa = require('koa');
    const koaBody = require('koa-body');
    const app = new Koa();
    
    const main = async function(ctx) {
      const body = ctx.request.body;
      if (!body.name){
          ctx.throw(400, '.name required');
      }
      ctx.body = { name: body.name };
    };
    
    app.use(koaBody());
    app.use(main);
    app.listen(3000);
    
3、文件上传
    const os = require('os');
    const path = require('path');
    const koaBody = require('koa-body');
    
    const main = async function(ctx) {
        const tmpdir = os.tmpdir();
        const filePaths = [];
        const files = ctx.request.body.files || {};
    
        for (let key in files) {
            const file = files[key];
            const filePath = path.join(tmpdir, file.name);
            const reader = fs.createReadStream(file.path);
            const writer = fs.createWriteStream(filePath);
            reader.pipe(writer);
            filePaths.push(filePath);
        }
    
        ctx.body = filePaths;
    };
    
    app.use(koaBody({ multipart: true }));

参考自阮一峰的网络日志


蔡万胜
625 声望40 粉丝

« 上一篇
axios学习笔记
下一篇 »
git命令笔记